
    /**  
    * @Title: CafeScheduleServiceImpl.java
    * @Package com.efast.cafe.commponent.job.service.impl
    * @Description: TODO(用一句话描述该文件做什么)
    * @author Administrator
    * @date 2018年9月13日
    * @version V1.0  
    */
    
package com.efast.cafe.commponent.job.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.matchers.NameMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import com.efast.cafe.commponent.job.base.AbstractStatefulJobBean;
import com.efast.cafe.commponent.job.bean.ScheduleJobBean;
import com.efast.cafe.commponent.job.bean.ScheduleJobParamBean;
import com.efast.cafe.commponent.job.bean.ScheduleJobQueryBean;
import com.efast.cafe.commponent.job.config.QuartzConfigUtil;
import com.efast.cafe.commponent.job.dao.QuartzTriggerMapper;
import com.efast.cafe.commponent.job.service.CafeScheduleService;
import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.framework.spring.SpringContextUtils;
import com.efast.cafe.util.ConfigUtil;
import com.efast.cafe.util.date.DateUtils;
import com.github.pagehelper.PageHelper;

/**
    * @ClassName: CafeScheduleServiceImpl
    * @Description: TODO(这里用一句话描述这个类的作用)
    * @author Administrator
    * @date 2018年9月13日
    *
    */
@Service
public class CafeScheduleServiceImpl implements CafeScheduleService {

	
	 @Autowired
	 private Scheduler scheduler;
	 
	 @Autowired
	 private QuartzTriggerMapper mapper;
	
	 private final static String groupName = ConfigUtil.getValue("spring.application.name");
	
	@Override
	public void addjob(String jobName,String jobClassName,
			String cronExpression,String jobDesc,Map<String, Object> params,boolean startNow)throws Exception  {
		
		JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
				.withIdentity(jobName, groupName).withDescription(jobDesc).build();
		//注入job参数
		if(null!=params && !params.isEmpty()){
			params.forEach((key,value)->{
				jobDetail.getJobDataMap().put(key, value);
			});
        }
		
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, groupName)
                .withSchedule(scheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, trigger);
        if(startNow){
        	resumejob(jobName);
        }
	}
	
	
	
	@Override
	public void modifyJob(String jobName,String jobClassName, String cronExpression, String jobDesc,
			Map<String, Object> params,boolean startNow) throws Exception {
		
		CronTrigger trigger = (CronTrigger) scheduler.getTrigger(TriggerKey.triggerKey(jobName, groupName));
		if (trigger == null) {
			return;
		}
		
		
		deletejob(jobName);
		addjob(jobName,jobClassName,cronExpression,jobDesc,params,startNow);
		
	}

	

	@Override
	public void pausejob(String jobName)throws Exception {
		 scheduler.pauseJob(JobKey.jobKey(jobName, groupName));
	}

	
	@Override
	public void resumejob(String jobName) throws Exception{
		scheduler.resumeJob(JobKey.jobKey(jobName, groupName));
	}

	
	@Override
	public void triggerJob(String jobName)throws Exception {
		JobKey jobKey = JobKey.jobKey(jobName, groupName);
    	if(scheduler.checkExists(jobKey)){
    		scheduler.triggerJob(jobKey,scheduler.getJobDetail(jobKey).getJobDataMap());
    	}
       //  scheduler.triggerJob(JobKey.jobKey(jobName, jobGroupName));

	}

	/* (非 Javadoc)
	* 
	* 
	* @param jobClassName
	* @param jobGroupName
	* @see com.efast.cafe.commponent.job.service.CafeScheduleService#deletejob(java.lang.String, java.lang.String)
	*/

	@Override
	public void deletejob(String jobName) throws Exception{
		scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, groupName));
        scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, groupName));
        scheduler.deleteJob(JobKey.jobKey(jobName, groupName));  
	}
	
	private Job getClass(String classname) throws Exception 
    {
        Class<?> class1 = Class.forName(classname);
        Object o = class1.newInstance();
        if(o instanceof AbstractStatefulJobBean){
        	return (AbstractStatefulJobBean)o;
        }
        return (Job)class1.newInstance();
    }

	@Autowired
	private SchedulerFactoryBean schedulerFactoryBean;

	
	    /* (非 Javadoc)
	    * 
	    * 
	    * @return
	    * @see com.efast.cafe.commponent.job.service.CafeScheduleService#getSchedulerInfo()
	    */
	    
	@Override
	public Map<String, Object> getSchedulerInfo() {
		Map<String, Object> map = new HashMap<>();
		try {
			map.put("started", scheduler.isStarted());
			map.put("jobSize", scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName)).size());
			map.put("isCluster", Boolean.parseBoolean(QuartzConfigUtil.getValue("org.quartz.jobStore.isClustered")));
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}



	
	    /* (非 Javadoc)
	    * 
	    * 
	    * @see com.efast.cafe.commponent.job.service.CafeScheduleService#resumeAllJobs()
	    */
	    
	@Override
	public void resumeAllJobs() throws Exception{
		scheduler.resumeAll();
	}



	
	    /* (非 Javadoc)
	    * 
	    * 
	    * @see com.efast.cafe.commponent.job.service.CafeScheduleService#pauseAllJobs()
	    */
	    
	@Override
	public void pauseAllJobs() throws Exception{
		// TODO Auto-generated method stub
		scheduler.pauseAll();
	}



	
	    /* (非 Javadoc)
	    * 
	    * 
	    * @return
	    * @see com.efast.cafe.commponent.job.service.CafeScheduleService#getAllJobs()
	    */
	    
	@Override
	public List<ScheduleJobBean> getAllJobs() throws Exception{
		List<ScheduleJobBean> list = new ArrayList<>();
		for (JobKey jobKey :scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))){
			String jobName = jobKey.getName();
            //get job's trigger
            List<CronTrigger> triggers = (List<CronTrigger>) scheduler.getTriggersOfJob(jobKey);
            CronTrigger trigger = triggers.get(0);
            Date nextFireTime = trigger.getNextFireTime();//下一次运行的时间
            org.quartz.Trigger.TriggerState state = scheduler.getTriggerState(trigger.getKey());//状态
            Date previousFireTime  = trigger.getPreviousFireTime();//上一次运行的时间
            String cron = trigger.getCronExpression();//表达式
            ScheduleJobBean job = new ScheduleJobBean();
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            job.setJobClass(jobDetail.getJobClass().toString().replaceAll("class ", ""));
            job.setJobDesc(jobDetail.getDescription());
            job.setCron(cron);
            job.setJobDesc(trigger.getDescription());
            job.setJobName(jobName);
            job.setNextFireTime(DateUtils.format(nextFireTime, DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
            job.setPreviousFireTime(DateUtils.format(previousFireTime, DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
            job.setState(state.name());//执行状态
            
            Set<Entry<String, Object>> set = jobDetail.getJobDataMap().entrySet();
            Iterator<Entry<String, Object>> it = set.iterator();
            List<ScheduleJobParamBean> params = new ArrayList<>();
            while(it.hasNext()){
           	 Entry<String, Object> et = it.next();
           	 ScheduleJobParamBean b = new ScheduleJobParamBean();
           	 b.setKey(et.getKey());
           	 b.setValue(et.getValue()!=null? et.getValue().toString():null);
           	 params.add(b);
            }
            job.setParams(params);
            
            list.add(job);
		}
		return list;
	}
	
	



	@Override
	public ScheduleJobQueryBean queryJobPageList(ScheduleJobQueryBean queryBean) {
		String tableF = QuartzConfigUtil.getValue("org.quartz.jobStore.tablePrefix");
		String tb_job = tableF+"job_details";
		String t_triggers = tableF+"triggers";
		String t_cron_triggers = tableF+"cron_triggers";
		queryBean.setTablePrefix(tableF);
		queryBean.setTableCronTriggers(t_cron_triggers);
		queryBean.setTableJobs(tb_job);
		queryBean.setTableTriggers(t_triggers);
		queryBean.setJobGroup(groupName);
		PageHelper.startPage(queryBean.getStart(), queryBean.getLength());
		List<ScheduleJobBean> list = mapper.queryJobPageList(queryBean);
		int count = mapper.queryCountList(queryBean);
		queryBean.setResultList(list);
		queryBean.setTotalRows(count);
		return queryBean;
	}



	@Override
	public ScheduleJobBean queryDetail(String jobName)throws Exception {
		 JobKey jobKey = JobKey.jobKey(jobName, groupName);
		 List<CronTrigger> triggers = (List<CronTrigger>) scheduler.getTriggersOfJob(jobKey);
         CronTrigger trigger = triggers.get(0);
         Date nextFireTime = trigger.getNextFireTime();//下一次运行的时间
         org.quartz.Trigger.TriggerState state = scheduler.getTriggerState(trigger.getKey());//状态
         Date previousFireTime  = trigger.getPreviousFireTime();//上一次运行的时间
         String cron = trigger.getCronExpression();//表达式
         ScheduleJobBean job = new ScheduleJobBean();
         JobDetail jobDetail = scheduler.getJobDetail(jobKey);
         job.setJobClass(jobDetail.getJobClass().toString().replaceAll("class ", ""));
         job.setJobDesc(jobDetail.getDescription());
         job.setCron(cron);
         job.setJobDesc(trigger.getDescription());
         job.setJobName(jobName);
         job.setNextFireTime(DateUtils.format(nextFireTime, DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
         job.setPreviousFireTime(DateUtils.format(previousFireTime, DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
         job.setState(state.name());//执行状态
         Set<Entry<String, Object>> set = jobDetail.getJobDataMap().entrySet();
         Iterator<Entry<String, Object>> it = set.iterator();
         List<ScheduleJobParamBean> params = new ArrayList<>();
         while(it.hasNext()){
        	 Entry<String, Object> et = it.next();
        	 ScheduleJobParamBean b = new ScheduleJobParamBean();
        	 b.setKey(et.getKey());
        	 b.setValue(et.getValue()!=null? et.getValue().toString():null);
        	 params.add(b);
         }
         job.setParams(params);
		return job;
	}



	
	   

}
